package com.aiwu;

import android.text.TextUtils;

import com.aiwu.bean.ConfigBean;
import com.aiwu.library.AiwuSimulator;
import com.aiwu.library.util.IOUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.citra.citra_emu.CitraApplication;
import org.citra.citra_emu.NativeLibrary;
import org.citra.citra_emu.features.settings.model.IntSetting;
import org.citra.citra_emu.features.settings.model.Setting;
import org.citra.citra_emu.features.settings.model.view.SettingsItem;
import org.citra.citra_emu.features.settings.utils.SettingsFile;

import java.io.File;

/**
 * 后台配置管理
 */
public class ConfigManager {
    private static final String[] new3DSGames = new String[]{
            "000400000F700000", // Xenoblade Chronicles 3D [JPN]
            "000400000F700100", // Xenoblade Chronicles 3D [USA]
            "000400000F700200", // Xenoblade Chronicles 3D [EUR]
            "000400000F70CC00", // Fire Emblem Warriors [USA]
            "000400000F70CD00", // Fire Emblem Warriors [EUR]
            "000400000F70C100", // Fire Emblem Warriors [JPN]
            "000400000F700800", // The Binding of Isaac: Rebirth [USA]
            "000400000F701700", // The Binding of Isaac: Rebirth [JPN]
            "000400000F700900", // The Binding of Isaac: Rebirth [EUR]
            "00040000000CCE00", // Donkey Kong Country Returns 3D [USA]
            "00040000000CC000", // Donkey Kong Country Returns 3D [JPN]
            "00040000000CCF00", // Donkey Kong Country Returns 3D [EUR]
            "0004000000127500", // Sonic Boom: Shattered Crystal [USA]
            "0004000000161300", // Sonic Boom: Fire & Ice [USA]
            "00040000001B8700", // Minecraft [USA]
    };
    //region原值
    public String originalGpuValue = "";
    public String originalAccurateMulValue = "";
    public String originalRegion = "";
    public String originalLanguage = "";
    public String originalIsNew3DS = "";
    //endregion
    public boolean gpuChanged = false;
    public boolean accurateMulChanged = false;
    public boolean regionChanged = false;
    public boolean languageChanged = false;
    public boolean isNew3DSChanged = false;
    //以上设置是否被用户更改
    public boolean settingChanged = false;

    //后台配置
    private ConfigBean configBean;

    public void handleConfigBean(String romId) {
        int isNew3DS = isNew3DSGame(romId) ? 1 : 0;
        if (configBean == null) {
            //先尝试读取配置文件
            readConfigFromFile();
        }
        if (configBean == null) {
            //重置一下，防止切换游戏配置没重置
            NativeLibrary.SetMyConfigValue(ConfigBean.DEFAULT_VALUE, ConfigBean.DEFAULT_VALUE, ConfigBean.DEFAULT_VALUE, ConfigBean.DEFAULT_VALUE, isNew3DS);
            NativeLibrary.SetRunningSettings(false, false);
            return;
        }
        int gpu = configBean.getUseAsynchronousGpuEmulation();
        int acc = configBean.getShadersAccurateMul();
        int regionValue = configBean.getRegionValue();
        int language = configBean.getLanguage();
        NativeLibrary.SetMyConfigValue(gpu, acc, regionValue, language, isNew3DS);
        int font = configBean.getFont();
        if (font != ConfigBean.DEFAULT_VALUE) {//配置了字体
            boolean success = Util.changeFont(font);
            if (success) {//切换成功
                PrefsHelper.getInstance().setFont(font);
            }
        }
        boolean skipSlowDraw = configBean.getSkipSlowDraw() == 1;
        boolean fmvHack = configBean.getFmvHack() == 1;
        NativeLibrary.SetRunningSettings(skipSlowDraw, fmvHack);
    }

    private boolean isNew3DSGame(String romId) {
        if (TextUtils.isEmpty(romId)) {
            return false;
        }
        for (String str : new3DSGames) {
            if (str.equalsIgnoreCase(romId)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 处理设置更改
     *
     * @param modifiedSetting 改了的设置
     */
    public void handleSettingChanged(SettingsItem modifiedSetting) {
        if (modifiedSetting == null) {
            return;
        }
        if (modifiedSetting.getKey().equalsIgnoreCase(SettingsFile.KEY_USE_ASYNCHRONOUS_GPU_EMULATION)) {
            gpuChanged = true;
        } else if (modifiedSetting.getKey().equalsIgnoreCase(SettingsFile.KEY_SHADERS_ACCURATE_MUL)) {
            accurateMulChanged = true;
        } else if (modifiedSetting.getKey().equalsIgnoreCase(SettingsFile.KEY_IS_NEW_3DS)) {
            isNew3DSChanged = true;
        } else if (modifiedSetting.getKey().equalsIgnoreCase(SettingsFile.KEY_REGION_VALUE)) {
            regionChanged = true;
        } else if (modifiedSetting.getKey().equalsIgnoreCase(SettingsFile.KEY_LANGUAGE)) {
            languageChanged = true;
        }
    }

    /**
     * 跳过设置或者恢复设置值
     * 被改过 就不操作了
     * 如果之前没有设置 并且没被改过 就跳过
     * 如果之前有设置 没被改过就恢复
     *
     * @param setting
     * @return 是否跳过这个设置
     */
    public boolean passSettingOrRestoreValue(Setting setting) {
        if (setting == null) {
            return true;
        }
        String key = setting.getKey();
        if (key.equalsIgnoreCase(SettingsFile.KEY_USE_ASYNCHRONOUS_GPU_EMULATION)) {
            if (gpuChanged) {
                //重新设置配置
                if (configBean != null) {
                    configBean.setUseAsynchronousGpuEmulation(ConfigBean.DEFAULT_VALUE);
                }
                gpuChanged = false;
                settingChanged = true;
            } else {
                return originalValue(setting, originalGpuValue);
            }
        } else if (key.equalsIgnoreCase(SettingsFile.KEY_SHADERS_ACCURATE_MUL)) {
            if (accurateMulChanged) {
                //重新设置配置
                if (configBean != null) {
                    configBean.setShadersAccurateMul(ConfigBean.DEFAULT_VALUE);
                }
                accurateMulChanged = false;
                settingChanged = true;
            } else {
                return originalValue(setting, originalAccurateMulValue);
            }
        } else if (key.equalsIgnoreCase(SettingsFile.KEY_REGION_VALUE)) {
            if (regionChanged) {
                //重新设置配置
                if (configBean != null) {
                    configBean.setRegionValue(ConfigBean.DEFAULT_VALUE);
                }
                regionChanged = false;
                settingChanged = true;
            } else {
                return originalValue(setting, originalRegion);
            }
        } else if (key.equalsIgnoreCase(SettingsFile.KEY_LANGUAGE)) {
            if (languageChanged) {
                //重新设置配置
                if (configBean != null) {
                    configBean.setLanguage(ConfigBean.DEFAULT_VALUE);
                }
                languageChanged = false;
                settingChanged = true;
            } else {
                return originalValue(setting, originalLanguage);
            }
        } else if (key.equalsIgnoreCase(SettingsFile.KEY_IS_NEW_3DS)) {
            if (isNew3DSChanged) {
                isNew3DSChanged = false;
                settingChanged = true;
            } else {
                return originalValue(setting, originalIsNew3DS);
            }
        }
        return false;
    }

    private boolean originalValue(Setting setting, String originalValue) {
        if (TextUtils.isEmpty(originalValue)) {
            //之前没有这个设置
            return true;
        } else {
            //恢复原值
            try {
                ((IntSetting) setting).setValue(Integer.parseInt(originalValue));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 如果需要，重置设置临时配置
     */
    public void resetTempConfigIfNecessary() {
        if (settingChanged) {
            //如果临时配置被用户改了那就要重新设置一下了
            if (configBean != null) {
                handleConfigBean(CitraApplication.getRomName());
            }
            settingChanged = false;
        }
    }

    /**
     * 快速配置里面用户是否可以配置SkipSlowDraw
     */
    public boolean getSkipSlowDrawVis() {
        return configBean == null || configBean.getSkipSlowDraw() != 0;
    }

    /**
     * 从本地配置文件读配置
     */
    private void readConfigFromFile() {
        File romFile = new File(AiwuSimulator.ROM_PATH);
        File file = new File(romFile.getParent(), ".config.aiwu");
        String jsonStr = IOUtil.readFile2String(file);
        if (TextUtils.isEmpty(jsonStr)) {
            return;
        }
        ConfigBean configBean = JSONObject.parseObject(jsonStr, ConfigBean.class);
        if (configBean != null) {
            this.configBean = configBean;
        }
    }

    /**
     * 保存配置到文件
     * 下次断网的时候可以读取
     * 文件名：.config.aiwu
     *
     * @param config 配置
     */
    public void saveConfig2File(ConfigBean config) {
        if (config == null) {
            return;
        }
        File romFile = new File(AiwuSimulator.ROM_PATH);
        File file = new File(romFile.getParent(), ".config.aiwu");
        String jsonStr = JSON.toJSONString(config);
        IOUtil.writeFileFromString(file, jsonStr);
    }

    /**
     * 快速配置里面用户是否可以配置FmvHack
     */
    public boolean getFmvHackVis() {
        return configBean == null || configBean.getFmvHack() != 0;
    }

    public void setOriginalGpuValue(String originalGpuValue) {
        this.originalGpuValue = originalGpuValue;
    }

    public void setOriginalAccurateMulValue(String originalAccurateMulValue) {
        this.originalAccurateMulValue = originalAccurateMulValue;
    }

    public void setOriginalRegion(String originalRegion) {
        this.originalRegion = originalRegion;
    }

    public void setOriginalLanguage(String originalLanguage) {
        this.originalLanguage = originalLanguage;
    }

    public void setOriginalIsNew3DS(String originalIsNew3DS) {
        this.originalIsNew3DS = originalIsNew3DS;
    }

    public void setConfigBean(ConfigBean configBean) {
        this.configBean = configBean;
    }

    private ConfigManager() {
    }

    public static ConfigManager getInstance() {
        return Holder.INSTANCE;
    }

    private static class Holder {
        private static ConfigManager INSTANCE = new ConfigManager();
    }
}
